#ifndef _SERILIZABLE_HPP_
#define _SERILIZABLE_HPP_

#include <string>
#include <iostream>
#include <sstream>

class Serializable {
 public:
  virtual std::string serialize() = 0;
  virtual Serializable* deserialize(std::string s) = 0;
};

class A : public Serializable {
 private:
  int data;
 public:
  A(int n) : data(n) {}

  int get_data() {
    return data;
  }

  std::string serialize() {
    std::stringstream ss;
    ss << "A:" << data;
    return ss.str();
  }

  Serializable* deserialize(std::string s) {
    std::stringstream ss;
    ss.str(s);
    char a;
    ss >> a;
    if (a == 'A') {
      int n;
      ss >> a >> n;
      return new A(n);
    } else {
      return 0;
    }
  }
};

class B : public Serializable {
 private:
  int data;
 public:
  B(int n) : data(n) {}

  int get_data() {
    return data;
  }

  std::string serialize() {
    std::stringstream ss;
    ss << "B:" << data;
    return ss.str();
  }

  Serializable* deserialize(std::string s) {
    std::stringstream ss;
    ss.str(s);
    char a;
    ss >> a;
    if (a == 'B') {
      int n;
      ss >> a >> n;
      return new B(n);
    } else {
      return 0;
    }
  }
};
             
class C : public Serializable {
 private:
  int data;
 public:
  C(int n) : data(n) {}

  int get_data() {
    return data;
  }

  void execute() {
    std::cout << "Executable C:" << data << std::endl;
  }

  std::string serialize() {
    std::stringstream ss;
    ss << "C:" << data;
    return ss.str();
  }

  Serializable* deserialize(std::string s) {
    std::stringstream ss;
    ss.str(s);
    char a;
    ss >> a;
    if (a == 'C') {
      int n;
      ss >> a >> n;
      return new A(n);
    } else {
      return 0;
    }
  }
};

#endif
